<?php 

namespace IMT\ServicesBundle\Controller;

use JMS\Serializer\SerializationContext;

use Symfony\Component\HttpFoundation\Request;

use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use FOS\RestBundle\View\View;
use FOS\Rest\Util\Codes;

class EventRestController extends Controller
{
	/**
	 * GET /event/{eventId}
	 *
	 * @param string $eventId
	 * @return Response
	 */
	public function getEventAction($eventId)
	{			
		if(intval($eventId) == 0)
	    	throw new \InvalidArgumentException(400, 'L\'id est incorrect : '.$eventId);
	    
    	// Récupération de l'event
    	$repository = $this->getDoctrine()->getRepository('IMTEventBundle:BaseEvent');
   		$event = $repository->findOneById($eventId);
   		
   		if (!$event)
   			throw new NotFoundHttpException('L\'event ayant l\'id '.$eventId.' n\'existe pas');
   		
   		
   		// Vérification des droits d'acces
   		$securityContext = $this->get('security.context');
   		
   		if(false === $securityContext->isGranted('VIEW', $event)){
   			throw new AccessDeniedException(403, 'Acces refuse pour '.$securityContext->getToken()->getUser()->getUsername());
   		}
   		
   		$context = new SerializationContext();
   		$context->setVersion('1.0');
   		$context->setGroups(array('event_details', 'account_list', 'order_list', 'attachment_list', 'user_list'));
   		 
		$view = View::create()
			->setStatusCode(200)
			->setData($event)
			->setSerializationContext($context);

		return $this->get('fos_rest.view_handler')->handle($view);
	}
	
	public function getEventCommentsAction($eventId)
	{
		if(intval($eventId) == 0)
			throw new \InvalidArgumentException(400, 'L\'id est incorrect : '.$eventId);
		 
		$request = $this->getRequest();
		
		// Récupération de l'event
		$repository = $this->getDoctrine()->getRepository('IMTEventBundle:BaseEvent');
		$event = $repository->findOneById($eventId);
		 
		if (!$event)
			throw new NotFoundHttpException('L\'event ayant l\'id '.$eventId.' n\'existe pas');
		 
		 
		// Vérification des droits d'acces
		$securityContext = $this->get('security.context');
		 
		if(false === $securityContext->isGranted('VIEW', $event)){
			throw new AccessDeniedException(403, 'Acces refuse pour '.$securityContext->getToken()->getUser()->getUsername());
		}
		
		$idThread = 'type['.$event->getType().']_channel[event_'.$event->getId().']';
		$thread = $this->container->get('fos_comment.manager.thread')->findThreadById($idThread);
			
		if (null === $thread) {
			$thread = $this->container->get('fos_comment.manager.thread')->createThread();
			$thread->setId($idThread);
			$thread->setPermalink($request->getUri());
				
			// Add the thread
			$this->container->get('fos_comment.manager.thread')->saveThread($thread);
		}
		
		$comments = $this->container->get('fos_comment.manager.comment')->findCommentsByThread($thread);
		$repository = $this->getDoctrine()->getRepository('IMTCommentBundle:Comment');
				 
		$resultComments = array();

		foreach($comments as $comment){
			$comment = $repository->findOneById($comment->getId());
			
			if($comment){
				$resultComments[] = array(
					'id' => $comment->getId(),
					'body' => $comment->getBody(),
					'author' => array(
						'username' => $comment->getAuthor()->getUsername()
					),
					'createdAt' => $comment->getCreatedAt()
				);
			}
		}
	
		$view = View::create()
			->setStatusCode(200)
			->setData($resultComments);
	
		return $this->get('fos_rest.view_handler')->handle($view);
	}
	
	public function getEventParticipantsAction($eventId)
	{
		if(intval($eventId) == 0)
			throw new \InvalidArgumentException(400, 'L\'id est incorrect : '.$eventId);
			
		$request = $this->getRequest();
	
		// Récupération de l'event
		$repository = $this->getDoctrine()->getRepository('IMTEventBundle:BaseEvent');
		$event = $repository->findOneById($eventId);
			
		if (!$event)
			throw new NotFoundHttpException('L\'event ayant l\'id '.$eventId.' n\'existe pas');
			
			
		// Vérification des droits d'acces
		$securityContext = $this->get('security.context');
			
		if(false === $securityContext->isGranted('VIEW', $event)){
			throw new AccessDeniedException(403, 'Acces refuse pour '.$securityContext->getToken()->getUser()->getUsername());
		}
	
		$context = new SerializationContext();
		$context->setVersion('1.0');
		$context->setGroups(array('participant_details', 'event_list', 'contact_details'));
		
		$view = View::create()
		->setStatusCode(200)
		->setData($event->getParticipants())
		->setSerializationContext($context);
	
		return $this->get('fos_rest.view_handler')->handle($view);
	}
	
	/**
	 * Creates a new Thread from the submitted data.
	 *
	 * @param Request $request The current request
	 *
	 * @return View
	 */
	public function postEventsAction(Request $request)
	{		
		$idEvent = 0;
		
		$em = $this->getDoctrine()->getEntityManager();
		$viewHandler = $this->get('fos_rest.view_handler');
			
		if('POST' == $request->getMethod()){
			$idEvent = $request->request->get('imt_event_form_general_idEvent');
			$type = $request->request->get('imt_event_form_general_type');
			
			$emEvent = $this->container->get('imt_event.'.$type.'_manager');
			$validator = $this->get('validator');
		
			if($idEvent == 0){
				$event = $emEvent->createEvent();
			} else {
				$event = $emEvent->findEventBy(array('id' => $idEvent));
				 
				if(!$event)
					throw $this->createNotFoundException('L\'événement à modifier n\'existe pas');
			}
			 
			$event = $emEvent->hydrateEvent($event, $request);
			$errors = $validator->validate($event);
			 
			if(count($errors) > 0){
				$return['errors'] = $errors;
				
				return $viewHandler->handle($this->createErrorViewResponse($return));
			} else {
				$emEvent->updateEvent($event);
				 
				$return['idEvent'] = $event->getId();
				
				return $viewHandler->handle($this->createSuccessViewResponse($return));
			}
		} else {
			throw new MethodNotAllowedException('POST');
		}
	
	}
	
	public function deleteEventAction($eventId)
	{
		if(intval($eventId) == 0)
	    	throw new \InvalidArgumentException(400, 'L\'id est incorrect : '.$eventId);
	    
    	// Récupération de l'event
    	$repository = $this->getDoctrine()->getRepository('IMTEventBundle:BaseEvent');
   		$event = $repository->findOneById($eventId);
   		
   		if (!$event)
   			throw new NotFoundHttpException('L\'event ayant l\'id '.$eventId.' n\'existe pas');
   		
   		$em = $this->getDoctrine()->getEntityManager();
		$viewHandler = $this->get('fos_rest.view_handler');
   		
   		// Vérification des droits d'acces
   		$securityContext = $this->get('security.context');
   		
   		if(false === $securityContext->isGranted('VIEW', $event)){
   			throw new AccessDeniedException(403, 'Acces refuse pour '.$securityContext->getToken()->getUser()->getUsername());
   		}
	
		$em->remove($event);
		$em->flush();
	
		return $viewHandler->handle($this->createSuccessViewResponse(array('idEvent' => $eventId)));
	}
	
	private function createSuccessViewResponse($return)
	{
		$view = View::create()
			->setStatusCode(200)
			->setData($return);
		
		return $view;
	}	
	
	private function createErrorViewResponse($return)
	{
		$view = View::create()
			->setStatusCode(Codes::HTTP_BAD_REQUEST)
			->setData($return);
	
		return $view;
	}
}